package at.codejedi.sto.gui.combat.tree;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import at.codejedi.sto.config.Configuration;
import at.codejedi.sto.gui.combat.tree.PlayerBattleTreeNode.DisplayType;
import at.codejedi.sto.model.combat.CombatLog;
import at.codejedi.sto.model.combat.IBattle;
import at.codejedi.sto.model.combat.IPlayer;
import at.codejedi.sto.model.combat.IPlayerBattle;

public class CombatLogTree extends JPanel {

	private static final long serialVersionUID = -1857867400156317187L;
	DefaultMutableTreeNode battleRootNode;
	DefaultMutableTreeNode playerRootNode;
	JTree tree;

	DefaultTreeModel treeModel;

	public CombatLogTree() {

		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
				"Combat Log");
		playerRootNode = new DefaultMutableTreeNode(
				Configuration.getLabel("Players"));
		battleRootNode = new DefaultMutableTreeNode(
				Configuration.getLabel("Battles"));

		rootNode.add(playerRootNode);
		rootNode.add(battleRootNode);

		treeModel = new DefaultTreeModel(rootNode);

		tree = new JTree(treeModel);
		tree.getSelectionModel().setSelectionMode(
				TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);

		tree.setRootVisible(false);
		JScrollPane treeView = new JScrollPane(tree);
		setLayout(new GridLayout(1, 1));
		add(treeView);

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				if (e.isPopupTrigger())
					myPopupEvent(e);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (e.isPopupTrigger())
					myPopupEvent(e);
			}

			private void myPopupEvent(MouseEvent e) {
				int x = e.getX();
				int y = e.getY();
				JTree tree = (JTree) e.getSource();
				TreePath path = tree.getPathForLocation(x, y);
				if (path == null)
					return;

				tree.setSelectionPath(path);

				Object obj = path.getLastPathComponent();

				String label = "popup: " + obj.toString();
				JPopupMenu popup = new JPopupMenu();
				popup.add(new JMenuItem(label));
				popup.show(tree, x, y);
			}
		});

	}

	public void addDetailSelectedActionListener(final ActionListener l) {

		tree.addTreeSelectionListener(new TreeSelectionListener() {

			@Override
			public void valueChanged(TreeSelectionEvent e) {
				List<Object> selectedNodeInfos = new ArrayList<Object>();

				for (TreePath path : tree.getSelectionPaths()) {
					DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
							.getLastPathComponent();
					Object nodeInfo = node.getUserObject();
					if (nodeInfo instanceof TreeNodeWrapper) {
						TreeNodeWrapper wrapper = (TreeNodeWrapper) nodeInfo;
						selectedNodeInfos.add(wrapper.getWrappedObj());
					} else {
						selectedNodeInfos.add(nodeInfo);
					}
				}

				/* if nothing is selected */
				if (selectedNodeInfos.size() == 0)
					return;

				/* retrieve the node that was selected */

				l.actionPerformed(new ActionEvent(selectedNodeInfos, 0, null));
			}
		});
	}

	public void displayCombatLog(CombatLog log) {
		{
			List<IPlayer> players = log.getPlayers();
			for (IPlayer player : players) {
				// original Tutorial
				DefaultMutableTreeNode playerNode = new DefaultMutableTreeNode(
						new PlayerTreeNode(player));
				treeModel.insertNodeInto(playerNode, playerRootNode, 0);

				List<IPlayerBattle> battles = player.getBattles();
				for (IPlayerBattle battle : battles) {
					DefaultMutableTreeNode battleNode = new DefaultMutableTreeNode(
							new PlayerBattleTreeNode(battle,
									DisplayType.BattleTime));
					treeModel.insertNodeInto(battleNode, playerNode, 0);
				}
			}
		}
		{
			List<IBattle> battles = log.getBattles();
			for (IBattle battle : battles) {
				// original Tutorial
				DefaultMutableTreeNode battleNode = new DefaultMutableTreeNode(
						new BattleTreeNode(battle));
				treeModel.insertNodeInto(battleNode, battleRootNode, 0);

				List<IPlayerBattle> players = battle.getPlayersMap();
				for (IPlayerBattle player : players) {
					// TODO: Display Player Name instead
					DefaultMutableTreeNode playerNode = new DefaultMutableTreeNode(
							new PlayerBattleTreeNode(player,
									DisplayType.PlayerName));
					treeModel.insertNodeInto(playerNode, battleNode, 0);
				}
			}
		}
		treeModel.reload();
	}

}
